package com.projectbox.web;

import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.projectbox.model.Folder;
import com.projectbox.model.Project;
import com.projectbox.model.Resource;
import com.projectbox.model.User;
import com.projectbox.service.ProjectService;
import com.projectbox.service.ResourceService;
import com.projectbox.service.SearchService;
import com.projectbox.service.UserService;

@Controller
@RequestMapping("/admin/projects")
public class ManageProjectController {
	private Logger logger = LoggerFactory.getLogger(getClass()); 

	private UserService userService;
	private ProjectService projectService;
	private ResourceService resourceService;
	private SearchService searchService;
	
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public void setProjectService(ProjectService projectService) {
		this.projectService = projectService;
	}
	
	public void setResourceService(ResourceService resourceService) {
		this.resourceService = resourceService;
	}
	
	public void setSearchService(SearchService searchService) {
		this.searchService = searchService;
	}
	
	@RequestMapping(method = RequestMethod.GET)
    public String displayProjects(Model model) {
		User user = userService.getCurrentUser();
		logger.debug(user.toString());
		model.addAttribute("user", user);
		
		model.addAttribute("projectList", projectService.findAllProjects());
	
		return "manageproject";
	}
	
	@RequestMapping(value = "/{pid}/contributor", method = RequestMethod.GET)
	public String viewContributor(@PathVariable Long pid, Model model) {
		model.addAttribute("user", userService.getCurrentUser());
		
		Project project = projectService.findProject(pid);
		if (project == null) {		
			return "redirect:/error/400.jsp";
		}
		model.addAttribute("project", project);
		model.addAttribute("manager", this.userService.findUser(project.getMid()));
		model.addAttribute("contributors", projectService.findProjectContributor(pid));
		
		return "adminProjectContributor";
	}
		
	@RequestMapping(value = "/{pid}/resource", method = RequestMethod.GET)
	public String viewResource(@PathVariable Long pid, Model model) {
		User user = userService.getCurrentUser();
		Project project = projectService.findProject(pid);
		if (project == null) {		
			return "redirect:/error/400.jsp";
		}
		
		List<Folder> folderList = resourceService.findSubfoldersByPid(pid);
		model.addAttribute("user", user);
		model.addAttribute("project", project);
		model.addAttribute("folders", folderList);
		model.addAttribute("resources", resourceService.findProjectResources(pid));
		
		return "adminProjectResource";
	}
	
	@RequestMapping(value = "/{pid}/{fid}/resource", method = RequestMethod.GET)
	public String displayResourceInFolder(@PathVariable("pid") Long pid, @PathVariable("fid") Long fid, Model model) {
		
		logger.debug("view resource in folder " + fid + " pid " + pid);		
		Project project = projectService.findProject(pid);
		if (project == null) {		
			return "redirect:/error/400.jsp";
		}
		
		Folder folder = resourceService.findFolder(fid);
		if (folder == null) {
			return "redirect:/error/400.jsp";
		}
		
		List<Folder> folderList = resourceService.findSubfolders(fid);
		List<Resource> resourceList = resourceService.findResourcesByFolder(fid);
		User user = userService.getCurrentUser();
		List<Folder> traceFolders = resourceService.findPreFoldersById(fid);
		
		
		logger.debug("" + project);
		logger.debug("" + folder.getName());
		logger.debug("fid" + folder.getId());
		logger.debug("" + folderList);
		logger.debug("" + resourceList);
		logger.debug("trace" + traceFolders);
	
		model.addAttribute("user", user);
		model.addAttribute("project", project);
		model.addAttribute("folders", folderList);
		model.addAttribute("resources", resourceList);		
		model.addAttribute("folder", folder);
		model.addAttribute("traceFolders", traceFolders);
		
		return "adminProjectResource";
	}

	
	// response "manageproject.jsp" delete link
	@RequestMapping(value = "/{pid}/remove", method = RequestMethod.GET)
	public String deleteProject(@PathVariable Long pid) {
		
		Project project = projectService.findProject(pid);
		if (project == null) {		
			return "redirect:/error/400.jsp";
		}
		
		this.projectService.deleteProject(pid);
		
		return "redirect:/admin/projects";
	}
	
	// response "adminProjectResource.jsp" delete link
	@RequestMapping(value = "/{pid}/resource/delete", method = RequestMethod.GET)
	public String processDeleteProjectResources(@PathVariable("pid") Long pid,
			@RequestParam(value = "rid", required = true) Long rid,
			HttpServletResponse response) throws IOException {
		
		Project project = projectService.findProject(pid);
		if (project == null) {		
			return "redirect:/error/400.jsp";
		}
		
		Resource resource = this.resourceService.findResource(rid);
		if (resource == null) {	
			return "redirect:/error/400.jsp";
		}
		
		this.resourceService.removeResource(resource);
		return "redirect:/admin/projects/" + pid + "/resource";
	}
	
	@RequestMapping(value = "/{pid}/{fid}/resource/delete", method = RequestMethod.GET)
	public String processDeleteResourcesInFolder(@PathVariable("pid") Long pid, @PathVariable("fid") Long fid,
			@RequestParam(value = "rid", required = true) Long rid,
			HttpServletResponse response) throws IOException {
		
		Project project = projectService.findProject(pid);
		if (project == null) {		
			return "redirect:/error/400.jsp";
		}
		
		Folder folder = resourceService.findFolder(fid);
		if (folder == null) {
			return "redirect:/error/400.jsp";
		}
		
		Resource resource = this.resourceService.findResource(rid);
		if (resource == null) {	
			return "redirect:/error/400.jsp";
		}
		
		this.resourceService.removeResource(resource);
		return "redirect:/admin/projects/" + pid + "/" + fid +  "/resource";
	}	
	
	// response "adminProjectContributor.jsp" delete link
	@RequestMapping(value = "/{pid}/contributor/delete", method = RequestMethod.GET)
	public String processDeleteProjectContributor(@PathVariable("pid") Long pid,
			@RequestParam(value = "uid", required = true) Long uid,
			HttpServletResponse response) throws IOException {
		
		Project project = projectService.findProject(pid);
		if (project == null) {		
			return "redirect:/error/400.jsp";
		}
		
		User contributor = this.userService.findUser(uid);
		if (contributor == null) {
			return "redirect:/error/400.jsp";
		}
		
		projectService.removeProjectContributor(pid, uid);
		return "redirect:/admin/projects/" + pid + "/contributor";
	}
	
	// response "adminProjectResource.jsp" download link
	@RequestMapping(value = "/{pid}/download", method = RequestMethod.GET)
	public void processDownloadProjectResources(@PathVariable("pid") Long pid,
			@RequestParam(value = "rid", required = true) Long rid,
			HttpServletResponse response) throws IOException {

		logger.debug("download resource");
		logger.debug("the pid " + pid);
		logger.debug("the rid " + rid);

		Project project = this.projectService.findProject(pid);
		if (project == null) {
			response.setStatus(400);
			return;
		}
		
		Resource resource = this.resourceService.findResource(rid);
		if (resource == null) {
			response.setStatus(400);
			return;
		}
		
		response.setContentType(resource.getType());
		response.setContentLength(resource.getFile().length);
		response.setHeader("Content-Disposition","attachment; filename=\""
        						+ resource.getName() +"\"");
		FileCopyUtils.copy(resource.getFile(), response.getOutputStream());
	}

	@RequestMapping(value = "/{pid}/{fid}/deleteFolder/resource", method = RequestMethod.GET)
	public String processDeleteFolder(@PathVariable("pid") Long pid, @PathVariable("fid") Long fid) throws IOException {
		
		Project project = projectService.findProject(pid);
		if (project == null) {		
			return "redirect:/error/400.jsp";
		}
		
		Folder root = resourceService.findFolder(fid);
		if (root == null) {
			return "redirect:/error/400.jsp";
		}
		
		this.resourceService.deleteFolder(fid);
		if(root.getPreId()==0)
			return "redirect:/admin/projects/" + pid + "/resource";
		else 
			return "redirect:/admin/projects/" + pid + "/" + root.getPreId() + "/resource";
	}
	
	@RequestMapping (value="/search", method = RequestMethod.GET)
	public String searchProjects(@RequestParam(value = "searchString", required = false) String topSearchString, Model model){
		User user = userService.getCurrentUser();
		
		model.addAttribute("user",user);
		model.addAttribute("searchString",topSearchString);
		
		model.addAttribute("projectList", searchService.searchProjects(user.getId(), topSearchString.toLowerCase(), "1970-01-01", "1970-01-01"));
		return "manageproject";
	}
}
